#include "ptwrap.hpp"
#include <nspr4/prtypes.h>
#include <nspr4/pratom.h>
#include <stdio.h>
#include <unistd.h>

// [[ex03ba]]
// DEBUG descr The basic hold.
class simplehold 
{
public:
	simplehold(int n) :
		count_(n)
	{ }

	void acquire()
	{
		PR_AtomicIncrement(&count_);
	}

	int release()
	{
		return PR_AtomicDecrement(&count_);
	}
protected:
	PRInt32 count_;
};
// END

// [[ex03bb]]
// DEBUG descr The basic hold with auto-deletion.
class autohold : public simplehold
{
public:
	autohold() :
		simplehold(1)
	{ }

	virtual ~autohold()  // allows polymorphism
	{ }

	int release()
	{
		int ret = simplehold::release();
		if (ret == 0)
			delete this;
		return ret;
	}
};
// END

// [[ex03bc]]
// DEBUG descr Usage of the basic hold with auto-deletion.
class someclass : public autohold
{
	// ...
};

// DEBUG from
void somecall(someclass *arg)
{
	arg->acquire();
	arg->release();
}

void ex03bc() // DEBUG
{
// DEBUG to
// ...
someclass *x = new someclass;
somecall(x);
x->release();
// ...
// END
}

void ex03bd() // DEBUG
{
// [[ex03bd]]
// ...
someclass *x = new someclass;
somecall(x);
// ...
// END
}

void ex03be() // DEBUG
{
// [[ex03be]]
// ...
someclass *x = new someclass;
x->acquire();
somecall(x);
x->release();
// ...
// END
}

// DEBUG {
class data : public autohold
{
public:
	~data()
	{
		fprintf(stderr, "destroyed data\n");
	}
};

int main()
{
	data *x = new data;
	x->release();
	x = new data;
	x->acquire();
	x->release();
	x->release();
	return 0;
}
// DEBUG }
/* Sample output:

destroyed data
destroyed data

*/
